<!--
*@Author: QWP
*@Description: 人事基本信息
*@Params: pType 1 人事信息录入    2 人事信息审核
*@Date 2024-09-29 09:55
-->
<template>
  <a-layout
    class="f-h-100 s-bg-white"
    id="test">
    <u-search-header>
      <u-form
        :model="searchF.model"
        :gutter="16"
        :elements="searchEl"
        class="f-w-auto"
        :isSearch="true"
        @formChange="getSearch(1)">
        <a-col>
          <a-space>
            <u-icon-button @click="getSearch(1)">查询</u-icon-button>
            <u-icon-button
              itype="record"
              @click="showFlow = true">
              流程记录
            </u-icon-button>
            <u-icon-button
              itype="filter"
              @click="showMoreSearch = true">
              筛选
            </u-icon-button>
            <u-icon-button
              itype="customCol"
              @click="showCustom = true">
              自定义列
            </u-icon-button>
            <u-dropdown
              :data="exportMenus"
              :buttonProps="{ itype: 'export' }"
              @click="exportBtn">
              导出
            </u-dropdown>
            <u-icon-button
              itype="unlock"
              @click="unLock"
              :loading="unlockLoading"
              v-if="isPersonManager">
              解锁
            </u-icon-button>
          </a-space>
        </a-col>
        <a-col flex="1">
          <a-row justify="end">
            <a-space>
              <template v-if="route.params.pType == 1">
                <u-icon-button
                  itype="add"
                  @click="toEdit(1)">
                  新增
                </u-icon-button>
                <u-icon-button
                  itype="edit"
                  @click="toEdit(2)">
                  修改
                </u-icon-button>
                <u-icon-button
                  itype="report"
                  @click="auditAbout('1')">
                  上报
                </u-icon-button>
                <u-icon-button
                  itype="recall"
                  @click="auditAbout('4')">
                  取回
                </u-icon-button>
                <u-icon-button
                  itype="delete"
                  @click="deleteBtn"
                  v-if="isPersonManager">
                  删除
                </u-icon-button>
              </template>
              <template v-else-if="route.params.pType == 2">
                <u-icon-button
                  itype="audit"
                  v-if="showAuditBnt"
                  @click="auditAbout('2')">
                  审核
                </u-icon-button>
                <u-icon-button
                  itype="recall"
                  @click="auditAbout('4')"
                  v-if="searchF.model.status == 3">
                  取回
                </u-icon-button>
                <u-icon-button
                  itype="close"
                  v-if="showAuditBnt"
                  @click="auditAbout('3')">
                  退回
                </u-icon-button>
              </template>
            </a-space>
          </a-row>
        </a-col>
      </u-form>
    </u-search-header>
    <u-table-content class="f-padding-rl24">
      <u-table
        :columns="columns"
        :data="tabData"
        :bordered="true"
        :loading="loading"
        v-model:pagination="pagenation"
        key="person-base-info"
        :scroll="{ y: useTableScroll() }"
        @onDblclick="
          (record) => {
            currentRow = record;
            showEdit = true;
          }
        "
        @onSelect="({ selectedRows }) => (tabSelData = selectedRows)"
        @change="getSearch"></u-table>
    </u-table-content>
  </a-layout>

  <!-- 高级筛选 -->
  <u-drawer-search
    v-model:open="showMoreSearch"
    v-model:value="searchF.model"
    :elements="moreSearchEl"
    @change="getSearch(1)" />

  <!-- 编辑弹窗 -->
  <Edit
    v-model:open="showEdit"
    width="70%"
    :title="dialogTitle"
    :current="currentRow"
    :isCheck="isCheck"
    :isAudited="showAuditBnt"
    wrap-class-name="full-modal"
    @close="(isCheck = false), (currentRow = {})"
    @success="(currentRow = {}), getSearch()"
    @detialSuccess="getSearch()" />
  <!-- showEdit = false,   -->

  <!-- 人员调动 -->
  <Transfer
    v-model:open="showTransfer"
    title="人员调动"
    :userInfo="currentRow"
    width="700px"
    @close="currentRow = {}"
    @success="(showTransfer = false), getSearch()" />

  <!-- 离退休 -->
  <LeaveOut
    v-model:open="showLeavOut"
    title="离退休编辑"
    :type="leavType"
    :userInfo="currentRow"
    width="700px"
    @close="currentRow = {}"
    @success="(showLeavOut = false), getSearch()" />

  <!-- 自定义列 -->
  <CustomCol
    v-model:open="showCustom"
    width="800px"
    @close="showCustom = false" />

  <!-- 自定导出模版 -->
  <CustomColExport
    v-model:open="showCustomExport"
    wrap-class-name="full-modal"
    :searchF="searchF"
    @close="showCustomExport = false" />

  <!-- 导出个人信息 -->
  <SelfInfoExport
    v-model:open="showSelfInfo"
    wrap-class-name="full-modal"
    :current="currentRow"
    @close="(showSelfInfo = false), (currentRow = {})" />

  <!-- 流程记录 -->
  <u-act-flowd
    v-model:open="showFlow"
    :selDatas="tabSelData"
    busiType="person_info" />
</template>

<script lang="ts" setup>
import { ref, reactive, computed, h, watch, onMounted, onActivated } from "vue";
import { useRoute, useRouter, onBeforeRouteUpdate, onBeforeRouteLeave } from "vue-router";
import { useBaseStore, useTableColStore, useLoginStore } from "@/store";
import { storeToRefs } from "pinia";
import { _IFormEl } from "@/components/common/form/interface";
import { ColProps, FormItemProps, TableColumnProps, Space, Button } from "ant-design-vue";
import { CheckCircleOutlined, ExclamationCircleOutlined } from "@ant-design/icons-vue";
import { numberC, alertC, messageC, nullC } from "@/util/common";
import { formatAmt } from "@/util/format.ts"
import { statusA } from "@/common/model/base";
import dayjs from "dayjs";
import Edit from "./Edit.vue";
import Transfer from "./Transfer.vue";
import LeaveOut from "./LeaveOut.vue";
import CustomCol from "./CustomCol.vue";
import CustomColExport from "./CustomColExport.vue";
import { cloneDeep } from "lodash";
import { useTableScroll } from "@/hooks/useTable";
import { TColumns, moreSearchEl, equiRenderCol, formatEnum } from "./data/colData.ts";
import { useAuditAbout, IAuditParams } from "@/hooks/useAudit";
import { usePageTypeShow, useSearchShow } from "@/hooks/useAuditEl";
import UIconFont from "@/components/common/iconfont/IconFont.vue";
import SelfInfoExport from "./SelfInfoExport.vue";
import { personInfoApi } from "@/service/personalSet";

const route = useRoute();
const router = useRouter();
const tableColStore = useTableColStore();
const { userInfo } = storeToRefs(useLoginStore());
const baseStore = useBaseStore();
const { APP_STATUS } = storeToRefs(baseStore);

const exportMenus = [
  { label: "导出当前列表", value: 1 },
  { label: "导出个人信息", value: 2 },
  { label: "自定义导出模版", value: 3 },
];

// 是否人事管理角色
const isPersonManager = computed(() => {
  let { roles } = userInfo.value["extra"] || {};
  let values = Object.values(roles).flat(2);
  return values.some((i) => i.attributeValue == "3");
});
// 是否部门领导角色
const isDeptLeader = computed(() => {
  let { roles } = userInfo.value["extra"] || {};
  let values = Object.values(roles).flat(2);
  return values.some((i) => i.attributeValue == "1");
});

const getRoleAttribute = () => {};

let pagenation = reactive({
  total: 0,
  current: 1,
  pageSize: 50,
  showTotal: (total) => `共 ${total} 条`,
});
const showMoreSearch = ref<boolean>(false);
let searchF = reactive({
  model: {
    keywords: null,
  },
  current: 1,
  size: 20,
});

// 曾经办，不显示审核和退回按钮
const showAuditBnt = ref<boolean>(useSearchShow(searchF.model, "3", { key: "status", result: false, noResult: true }));

const formItemProps: FormItemProps = {
  labelWidth: "72px",
  wrapperCol: { span: 24 },
};
const searchEl: Array<_IFormEl> = [
  {
    label: "审核状态",
    key: "status",
    element: "select",
    col: { span: 4 },
    formItemProps: formItemProps,
    componentProps: {
      options: computed(() => statusA(route.params.pType)),
      allowClear: route.params.pType == 2 ? false : true,
    },
  },
  {
    label: "关键字",
    key: "keywords",
    element: "input",
    col: { span: 4 },
    formItemProps: formItemProps,
    componentProps: { placeholder: "姓名" },
  },
];

// 列表
const loading = ref<boolean>(false);
const tabData = ref<any[]>([{}]);
const tabSelData = ref<any[]>([]);
const sustomeRenderCols = ref<any[]>([]);
let columns: Array<TableColumnProps> = computed(() => {
  return [
    { dataIndex: "index", title: "序号", width: 50, align: "center", customRender: ({ index }) => (index += 1) },
    ...(tableColStore.getCols.length == 0 ? TColumns : sustomeRenderCols.value),
    { dataIndex: "taskname", title: "审核节点", width: 100, align: "center" },
    { dataIndex: "reauditusername", title: "当前审核人", width: 150, align: "center", fixed: "right" },
    {
      dataIndex: "status",
      title: "锁定状态",
      width: 80,
      align: "center",
      fixed: "right",
      customRender: ({ text }) => (["2", "3"].includes(text + "") ? "已锁定" : "未锁定"),
    },
    ...(isPersonManager.value
      ? [
          {
            dataIndex: "do",
            title: "操作",
            width: 100,
            align: "center",
            fixed: "right",
            customRender: ({ record }) => {
              return h(Space, { size: 24, style: { color: "#1890ff", cursor: "pointer", fontSize: "18px" } }, [
                h(UIconFont, {
                  type: "icon-faqitiaodong",
                  title: "发起调岗",
                  onClick: () => {
                    showTransfer.value = true;
                    currentRow.value = record;
                  },
                }),
                h(UIconFont, {
                  type: "icon-banlilizhi",
                  title: "离退休办理",
                  onClick: () => {
                    currentRow.value = record;
                    showLeavOut.value = true;
                  },
                }),
              ]);
            },
          },
        ]
      : []),
  ];
});

watch(
  () => tableColStore.getCols,
  (nval) => {
    sustomeRenderCols.value = equiRenderCol(tableColStore.getCols);
  },
  { immediate: true }
);

// 编辑
let dialogTitle = ref<string>("人事信息");
let showEdit = ref<boolean>(false);
let showTransfer = ref<boolean>(false);
let showLeavOut = ref<boolean>(false);
let leavType = ref<string>("");
let showCustom = ref<boolean>(false);
let showCustomExport = ref<boolean>(false);
let isCheck = ref<boolean>(false);
let showSelfInfo = ref<boolean>(false);
let showFlow = ref<boolean>(false);
let currentRow = ref<object>({});

onMounted(() => {
  initCols();
});

// 列表查询
const getSearch = async (current?: number) => {
  console.time('test')
  if (current == 1) {
    pagenation.current = current;
  }
  loading.value = true;
  try {
    let tform = cloneDeep(searchF);
    searchF.current = pagenation.current;
    searchF.size = pagenation.pageSize;
    
    const data = await personInfoApi.page(searchF);
    
    formattabData(data.data.records || []);
    
    pagenation.total = data.data.total;
    tabSelData.value = [];
    loading.value = false;
  } catch (error) {}
  loading.value = false;
  console.timeEnd('test')
};

// 格式化列表数据
const formattabData = (data: any[]) => {
  const dyKeys = {
    technical: {
      key: "perTechnicals",
      keys: [
        { colKey: "technicalLevle", key: "technicalLevle", type: "enum", data: baseStore.storetechLevels },
        { colKey: "technicalProfession", key: "technicalProfession" },
        { colKey: "tecApprovalDate", key: "tecApprovalDate", type: "date", format: "YYYY-MM-DD" },
        { colKey: "tecUnit", key: "tecUnit" },
      ],
    },
    certificate: {
      key: "perCredentials",
      keys: [
        { colKey: "credentialName", key: "credentialName" },
        { colKey: "credentialStats", key: "credentialStats", type: "enum", data: baseStore.storecredentialStats },
        { colKey: "creApprovalDate", key: "creApprovalDate", type: "date", format: "YYYY-MM-DD" },
        { colKey: "creUnit", key: "creUnit" },
        { colKey: "creValidity", key: "creValidity" },
      ],
    },
    educationInit: {
      key: "perDegreeInitVos",
      keys: [
        { colKey: "degreeNameInit", key: "degreeNameInit", type: "enum", data: baseStore.storeeducations },
        { colKey: "certificateInit", key: "certificateInit", type: "enum", data: baseStore.storecertificate, matchType: "multiple" },
        { colKey: "graduationTimeInit", key: "graduationTimeInit", type: "date", format: "YYYY-MM-DD" },
        { colKey: "schoolInit", key: "schoolInit" },
        { colKey: "professionInit", key: "professionInit" },
      ],
    },
    educationMax: {
      key: "perDegreeMaxVos",
      keys: [
        { colKey: "degreeNameMax", key: "degreeNameMax", type: "enum", data: baseStore.storeeducations },
        { colKey: "degreeFormMax", key: "degreeFormMax", type: "enum", data: baseStore.storedegreeForm },
        { colKey: "degreeCertificateMax", key: "degreeCertificateMax", type: "enum", data: baseStore.storedegreeCertificate },
        { colKey: "professionTypeMax", key: "professionTypeMax", type: "enum", data: baseStore.storeprofessionTypes },
      ],
    },
    educationJob: {
      key: "perDegreeJobVos",
      keys: [
        { colKey: "degreeNameJob", key: "degreeNameJob", type: "enum", data: baseStore.storeeducations },
        { colKey: "certificateJob", key: "certificateJob", type: "enum", data: baseStore.storecertificate, matchType: "multiple" },
        { colKey: "graduationTimeJob", key: "graduationTimeJob", type: "date", format: "YYYY-MM-DD" },
        { colKey: "schoolJob", key: "schoolJob" },
        { colKey: "professionJob", key: "professionJob" },
      ],
    },
    job: {
      key: "perJobs",
      keys: [
        { colKey: "job", key: "job" },
        { colKey: "approvalDate", key: "approvalDate", type: "date", format: "YYYY-MM-DD" },
      ],
    },
    contract: {
      key: "perContracts",
      firstData: true,
      sort: {
        key: "endDate",
        type: "date",
        order: "desc",
      },
      keys: [
        { colKey: "conBeginDate1", key: ["conBeginDate", "conEndDate"], type: "date", format: "YYYY-MM-DD" },
        { colKey: "conUnit", key: "conUnit" },
      ],
    },
    expert: {
      key: "perAppointedExperts",
      keys: [
        { colKey: "expertName", key: "expertName" },
        { colKey: "expertGroup", key: "expertGroup", type: "enum", data: baseStore.storeexpertGroup },
        { colKey: "expertUnit", key: "expertUnit" },
        { colKey: "expBeginDate1", key: ["expBeginDate", "expEndDate"], type: "date", format: "YYYY-MM-DD" },
      ],
    },
    outsend: {
      key: "perDispatches",
      keys: [{ colKey: "dispatchCause", key: "dispatchCause" }],
    },
    scientific: {
      key: "perScientificResearches",
      keys: [
        { colKey: "scientificResearchType", key: "scientificResearchType", type: "enum", data: baseStore.storescientificResearchType },
        // { colKey: 'approvalDate', key: 'approvalDate',  type: 'date', format: 'YYYY-MM-DD' }
      ],
    },
    award: {
      key: "perCommends",
      keys: [
        { colKey: "commendDate", key: "commendDate", type: "date", format: "YYYY-MM-DD" },
        { colKey: "commendUnit", key: "commendUnit" },
        { colKey: "commendName", key: "commendName" },
        { colKey: "commendLevel", key: "commendLevel", type: "enum", data: baseStore.storeawardLevels },
      ],
    },
    punish: {
      key: "perPunishments",
      keys: [
        { colKey: "punishmentDate", key: "punishmentDate", type: "date", format: "YYYY-MM-DD" },
        { colKey: "punUnit", key: "punUnit" },
        { colKey: "punishmentName", key: "punishmentName" },
        { colKey: "influence", key: "influence" },
        { colKey: "rests", key: "rests" },
      ],
    },
    yearcheck: {
      key: "perAnnualAssessments",
      firstData: true,
      sort: {
        key: "annualAssessmentDate",
        type: "date",
        order: "desc",
      },
      keys: [
        { colKey: "annualAssessmentDate", key: "annualAssessmentDate", type: "date", format: "YYYY年" },
        { colKey: "annualAssessmentLevle", key: "annualAssessmentLevle", type: "enum", data: baseStore.storeannualAssessmentLevle },
      ],
    },
    family: {
      key: "perFamilies",
      keys: [
        { colKey: "famRelation", key: "famRelation" },
        { colKey: "famName", key: "famName" },
        { colKey: "famBirthDate", key: "famBirthDate", type: "date", format: "YYYY-MM" },
        { colKey: "famPolitcalStatus", key: "famPolitcalStatus" },
        { colKey: "famUnit", key: "famUnit" },
      ],
    },
    emergencyLink: {
      key: "perPhones",
      keys: [
        { colKey: "phoneNub1", key: ["relation", "phoneNub"] }, // 'phoneName',
      ],
    },
    // education: 'perDegrees',
  };
  data.forEach((item) => {
    for (let key in dyKeys) {
      let keyItem = dyKeys[key];
      let itemDatas = item[keyItem["key"]] || [];

      if (key == "job") {
        itemDatas = itemDatas.filter((i) => i.isPresentPosition == "1");
      }

      if (itemDatas.length == 0) {
        continue;
      }

      let firstData = keyItem["firstData"] || false;
      if (firstData == true) {
        itemDatas = [sortDetialArr(itemDatas, keyItem["sort"] || {})[0]];
      }

      (keyItem["keys"] || []).forEach((child) => {
        if (child.key instanceof Array) {
          item[child.colKey] = itemDatas
            .map((o, index) => {
              let dR = `${index + 1}.`;
              dR += child.key
                .map((i) => {
                  if (child["type"] == "date") {
                    return `${o[i] ? dayjs(o[i]).format(child.format) : "无"}`;
                  } else {
                    return `${o[i] ? o[i] : "无"}`;
                  }
                })
                .join("/");

              return dR;
            })
            .join("\n");
        } else {
          item[child.colKey] = itemDatas
            .map((o, index) => {
              if (child["type"] == "date") {
                return firstData
                  ? `${o[child.key] ? dayjs(o[child.key]).format(child.format) : "无"}`
                  : `${index + 1}.${o[child.key] ? dayjs(o[child.key]).format(child.format) : "无"}`;
              } else if (child["type"] == "enum") {
                return firstData
                  ? `${nullC(formatEnum(o[child.key], child.data || [], child["matchType"] || "single"), "无")}`
                  : `${index + 1}.${nullC(formatEnum(o[child.key], child.data || [], child["matchType"] || "single"), "无")}`;
              } else {
                return firstData ? `${nullC(o[child.key], "无")}` : `${index + 1}.${nullC(o[child.key], "无")}`;
              }
            })
            .join("\n");
        }
      });
    }
  });
  tabData.value = data;
};

// 排序详细项数据
const sortDetialArr = (data, sort) => {
  if (sort["type"] == "date") {
    return data.sort((a, b) =>
      sort["order"] == "desc" ? dayjs(b[sort["key"]]) - dayjs(a[sort["key"]]) : dayjs(a[sort["key"]]) - dayjs(b[sort["key"]])
    );
  }
  return data.sort((a, b) => (sort["order"] == "desc" ? b[sort["key"]] - a[sort["key"]] : a[sort["key"]] - b[sort["key"]]));
};

// 初始化列表表头
const initCols = (to?) => {
  let tTo = to ? to : route;
  // const isAudit = {
  //   1: '0', 2: '1', 3: '2'
  // }

  searchF.model.pageStatus = numberC(tTo.params.pType);
  if (searchF.model.pageStatus == 2) {
    searchF.model.status = "2";
  }

  // searchF.model.isAudit = isAudit[route.params.pType]

  setSearchRoleType();

  getSearch();
};

const setSearchRoleType = () => {
  let { roles } = userInfo.value["extra"] || {};
  let rolType1 = (roles || {})["1"] || [];
  rolType1.some((i) => i.keyid == "1");

  if (isPersonManager) {
    searchF.model.roleType = 2;
  } else if (isDeptLeader) {
    searchF.model.roleType = 3;
  }
  // 系统管理员
  else if (rolType1.some((i) => i.keyid == "1")) {
    searchF.model.roleType = 1;
  } else {
    searchF.model.roleType = 0;
  }
};

onActivated(() => {
  initCols(route);
});

// type 1 新增、  2 编辑
const toEdit = (type: number) => {
  if (type == 2) {
    if (tabSelData.value.length != 1) {
      alertC("能且只能选择一条数据进行编辑！");
      return;
    }
    currentRow.value = tabSelData.value[0];
  }
  showEdit.value = true;
  dialogTitle.value = "人事信息";
};

// 删除
const deleteBtn = () => {
  if (tabSelData.value.length == 0) {
    messageC("请先选择要删除的数据!", "warning");
    return;
  }

  let noDel = tabSelData.value.some((i) => ["2", "3"].includes(i["status"] + ""));
  if (noDel) {
    messageC("审核中或审核完成的数据不能删除!");
    return;
  }

  let ids = tabSelData.value.map((item) => item.keyid);
  alertC("确定删除选中的数据?", "confirm").then(async () => {
    try {
      loading.value = true;
      const data = await personInfoApi.del({ ids: ids.join(",") });
      if (data.code == 0) {
        messageC(data.msg, "success");
        getSearch();
      } else {
        alertC(data.msg, "warning");
      }
      loading.value = false;
    } catch (error) {
      loading.value = false;
    }
  });
};

// 解锁
const unlockLoading = ref<boolean>(false);
const unLock = async () => {
  if (tabSelData.value.length == 0) {
    messageC("请先选择需要解锁的数据!");
    return;
  }

  unlockLoading.value = true;
  try {
    const ids = tabSelData.value.map((i) => i.keyid);
    const res = await personInfoApi.unlock(ids.join(","));
    if (res.code == 0) {
      messageC(res.msg, "success");
      getSearch();
    } else {
      messageC(res.msg, "error");
    }
  } catch (error) {}
  unlockLoading.value = false;
};

// 上报、审核、退回
const auditAbout = async (type: string) => {
  loading.value = true;
  const auditParams: IAuditParams = {
    type: "person_info",
    selDatas: tabSelData.value,
  };
  try {
    const res = await useAuditAbout(type, auditParams);
    if (res) {
      pagenation.current = 1;
      getSearch();
    }
  } catch (error) {}
  loading.value = false;
};

// 导出
const exportBtn = async (value, option) => {
  // 导出当前列表
  if (value == 1) {
    try {
      loading.value = true;
      let tSesarchF = cloneDeep(searchF);
      tSesarchF.model.templateId = 1;
      const res = await personInfoApi.download({ ...tSesarchF, size: 100000, filename: "人事信息" });
      loading.value = false;
    } catch (error) {}
    loading.value = false;
  }
  // 导出个人信息
  else if (value == 2) {
    if (tabSelData.value.length != 1) {
      messageC("只能选择一条数据进行个人信息导出！");
      return;
    }
    currentRow.value = tabSelData.value[0];
    showSelfInfo.value = true;
  }
  // 导出自定义模板
  else if (value == 3) {
    showCustomExport.value = true;
  }
};
</script>

<style lang="scss" scoped>
.icons-list :deep(.anticon) {
  margin-right: 6px;
  font-size: 24px;
}
:deep(.ant-table-thead) {
  .ant-table-cell {
    border-color: #e0e7ec !important;
  }
}
</style>
